gdk/wayland: Avoid idempotent wl_subsurface.set_position calls
authorMatthias Clasen <mclasen@redhat.com>
Sun, 19 Aug 2018 01:21:46 +0000 (01:21 +0000)
committerMatthias Clasen <mclasen@redhat.com>
Sun, 19 Aug 2018 01:26:20 +0000 (01:26 +0000)
These may not result on wl_surface.frame callbacks, yet we do trigger
a frame clock tick that would get stuck on the lack of such callback.

https://bugzilla.gnome.org/show_bug.cgi?id=784314
https://gitlab.gnome.org/GNOME/gtk/issues/844

Closes: #844
gdk/wayland/gdksurface-wayland.c

index d8d2a02d0b05c3be076bd7498797170ccad776d2..48dd1a4cbb14d3ea7a48bc1426dd5ef514e7b003 100644 (file)
@@ -140,6 +140,9 @@ struct _GdkSurfaceImplWayland
   int pending_buffer_offset_x;
   int pending_buffer_offset_y;
 
+  int subsurface_x;
+  int subsurface_y;
+
   gchar *title;
 
   struct {
@@ -1109,6 +1112,22 @@ on_parent_surface_committed (GdkSurfaceImplWayland *parent_impl,
   gdk_wayland_set_input_region_if_empty (surface);
 }
 
+static void
+gdk_wayland_surface_set_subsurface_position (GdkSurface *surface,
+                                             int         x,
+                                             int         y)
+{
+  GdkSurfaceImplWayland *impl;
+
+  impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+
+  wl_subsurface_set_position (impl->display_server.wl_subsurface, x, y);
+  impl->subsurface_x = x;
+  impl->subsurface_y = y;
+
+  gdk_surface_request_transient_parent_commit (surface);
+}
+
 static void
 gdk_wayland_surface_create_subsurface (GdkSurface *surface)
 {
@@ -1132,9 +1151,6 @@ gdk_wayland_surface_create_subsurface (GdkSurface *surface)
       impl->display_server.wl_subsurface =
         wl_subcompositor_get_subsurface (display_wayland->subcompositor,
                                          impl->display_server.wl_surface, parent_impl->display_server.wl_surface);
-      wl_subsurface_set_position (impl->display_server.wl_subsurface,
-                                  surface->x + surface->abs_x,
-                                  surface->y + surface->abs_y);
 
       /* In order to synchronize the initial position with the initial frame
        * content, wait with making the subsurface desynchronized until after
@@ -1144,7 +1160,9 @@ gdk_wayland_surface_create_subsurface (GdkSurface *surface)
         g_signal_connect_object (parent_impl, "committed",
                                  G_CALLBACK (on_parent_surface_committed),
                                  surface, 0);
-      gdk_surface_request_transient_parent_commit (surface);
+      gdk_wayland_surface_set_subsurface_position (surface,
+                                                   surface->x + surface->abs_x,
+                                                   surface->y + surface->abs_y);
     }
 }
 
@@ -2889,12 +2907,13 @@ gdk_surface_wayland_move_resize (GdkSurface *surface,
           surface->y = y;
           impl->position_method = POSITION_METHOD_MOVE_RESIZE;
 
-          if (impl->display_server.wl_subsurface)
+          if (impl->display_server.wl_subsurface &&
+              (x + surface->abs_x != impl->subsurface_x ||
+               y + surface->abs_y != impl->subsurface_y))
             {
-              wl_subsurface_set_position (impl->display_server.wl_subsurface,
-                                          surface->x + surface->abs_x,
-                                          surface->y + surface->abs_y);
-              gdk_surface_request_transient_parent_commit (surface);
+              gdk_wayland_surface_set_subsurface_position (surface,
+                                                           x + surface->abs_x,
+                                                           y + surface->abs_y);
             }
         }
     }